package handler

import (
	"kop/modules/guild/entity"
	"kop/pb"
	"kop/util/date"
	"sync"
	"time"
)

type ManagerMap struct {
	sync.RWMutex
	Map map[int32]*Manager
}

func (m *ManagerMap) Get(guildID int32) *Manager {

	m.RLock()
	defer m.RUnlock()
	return m.Map[guildID]
}

func (m *ManagerMap) Add(guildID int32, manager *Manager) {

	m.Lock()
	defer m.Unlock()

	if _, ok := m.Map[guildID]; !ok {
		m.Map[guildID] = manager
	}
}

func (m *ManagerMap) Del(guildID int32) {

	m.Lock()
	defer m.Unlock()

	if manager, ok := m.Map[guildID]; ok {
		manager.done <- true
	}

	delete(m.Map, guildID)
}

type Manager struct {
	sync.RWMutex
	Guild       *entity.Guild
	members     []*pb.GuildMember
	Declaration string
	done        chan bool
}

func NewManager(guild *entity.Guild, members []*pb.GuildMember) *Manager {

	var manager = Manager{
		Guild:   guild,
		members: members,
		done:    make(chan bool, 1),
	}

	return &manager
}

func (m *Manager) Online(roleID int32) {

	for _, member := range m.GetMembers() {
		if member.RoleID == roleID {
			member.OnlineTime = time.Now().Unix()
		}
	}
}

func (m *Manager) Offline(roleID int32) {

	for _, member := range m.GetMembers() {
		if member.RoleID == roleID {
			member.OnlineTime = 0
		}
	}
}

func (m *Manager) AllOffline() bool {

	var allOffline = true
	for _, v := range m.GetMembers() {
		if v.OnlineTime > 0 {
			allOffline = false
		}
	}

	return allOffline
}

func (m *Manager) GetPower() int64 {

	var power int64
	for _, v := range m.GetMembers() {
		power += v.Power
	}
	return power
}

func (m *Manager) GetMembers() []*pb.GuildMember {

	var day = date.Date(time.Now())
	var unixTime = time.Now().Unix()

	for _, member := range m.members {

		if member.BuildDate != day {
			member.BuildType = pb.GuildBuildType_GuildNotBuild
		}

		if member.OnlineTime > 0 {
			member.OnlineSecond = int32(unixTime - member.OnlineTime)
		}

	}
	return m.members
}

func (m *Manager) AddMember(member *pb.GuildMember) {

	for _, v := range m.GetMembers() {
		if v.RoleID == member.RoleID {
			return
		}
	}

	m.members = append(m.members, member)
	m.Guild.MemberNum = int32(len(m.GetMembers()))
	m.Guild.Power = m.GetPower()
}

func (m *Manager) DelMember(member *pb.GuildMember) {

	var newMembers = make([]*pb.GuildMember, 0, len(m.GetMembers()))

	for _, v := range m.GetMembers() {
		if v.RoleID != member.RoleID {
			newMembers = append(newMembers, v)
		}
	}

	m.members = newMembers
	m.Guild.MemberNum = int32(len(m.GetMembers()))
	m.Guild.Power = m.GetPower()
}

func (m *Manager) GetPresident() *pb.GuildMember {

	for _, m := range m.GetMembers() {
		if m.Position == pb.GuildPosition_President {
			return m
		}
	}
	return nil
}

func (m *Manager) GetMember(roleID int32) *pb.GuildMember {

	for _, v := range m.GetMembers() {
		if v.RoleID == roleID {
			return v
		}
	}

	return nil
}

func (m *Manager) Work(f func(manager *Manager)) {

	f(m)

	go func() {
		var ticker = time.NewTicker(time.Minute * 10)
		for {

			select {
			case <-ticker.C:
				// 10 分钟同步一次 数据
				f(m)

			case <-m.done:
				return
			}
		}
	}()
}
